package com.xqboss.web.controller.user;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xqboss.apps.convert.user.WithdrawConverter;
import com.xqboss.apps.domain.consumer.ConsumerRealName;
import com.xqboss.apps.domain.user.SysUserWalletWithdraw;
import com.xqboss.apps.domain.user.SysUserWalletWithdrawHandler;
import com.xqboss.apps.dto.user.GetWithdrawListDto;
import com.xqboss.apps.dto.user.WithdrawBatchProcessDto;
import com.xqboss.apps.dto.user.WithdrawProcessDto;
import com.xqboss.apps.enums.user.WithdrawStatusEnum;
import com.xqboss.apps.service.consumer.ConsumerRealNameService;
import com.xqboss.apps.service.user.SysUserWalletWithdrawHandlerService;
import com.xqboss.apps.service.user.SysUserWalletWithdrawService;
import com.xqboss.apps.vo.user.*;
import com.xqboss.common.annotation.Log;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.enums.BusinessType;
import com.xqboss.common.exception.ServiceException;
import com.xqboss.common.utils.LocalDateUtils;
import com.xqboss.common.utils.poi.ExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 用户钱包相关控制器
 * </p>
 *
 * @author Trent
 * @date 2023/8/17
 */

@Api(tags = "钱包-用户钱包提现管理")
@RestController("WebUserWalletWithdrawController")
@RequestMapping("/web/user/wallet/withdraw")
public class UserWalletWithdrawController extends BaseController {

    @Autowired
    private SysUserWalletWithdrawService userWalletWithdrawService;

    @Autowired
    private SysUserWalletWithdrawHandlerService userWalletWithdrawHandlerService;

    @Autowired
    private ConsumerRealNameService consumerRealNameService;

    @Autowired
    private WithdrawConverter withdrawConverter;

    /**
     * 提现列表
     *
     * @return
     */

    @PreAuthorize("@ss.hasPermi('web:user:withdraw:list')")
    @ApiOperation("提现列表")
    @GetMapping("list")
    public R<List<WithdrawListVo>> withdrawList(@Validated GetWithdrawListDto params) {
        startPage();
        List<WithdrawListVo> list = userWalletWithdrawService.getVoList(params);
        return R.ok(list);
    }

    /**
     * 提现详情
     *
     * @return
     */
    @PreAuthorize("@ss.hasPermi('web:user:withdraw:detail')")
    @ApiOperation("提现详情")
    @GetMapping("detail/{withdrawId}")
    public R<WithdrawDetailVo> withdrawList(@Validated @PathVariable("withdrawId")
                                            @ApiParam(value = "提现ID", required = true)
                                            @NotNull(message = "提现ID不能为空")
                                            Long withdrawId) {
        WithdrawListVo detail = userWalletWithdrawService.getDetail(withdrawId);
        // 用户实名信息
        ConsumerRealName realNameInfo = consumerRealNameService.getUserRealNameOrNull(detail.getUserId());
        // 用户提现处理记录
        List<SysUserWalletWithdrawHandler> handlerList = userWalletWithdrawHandlerService.getWithdrawHandlerList(detail.getId());
        WithdrawDetailVo result = withdrawConverter.toWithdrawDetailVo(detail, handlerList, realNameInfo);
        return R.ok(result);
    }

    /**
     * 获取提现处理列表
     *
     * @return
     */
    @PreAuthorize("@ss.hasPermi('web:user:withdraw:handler:list')")
    @ApiOperation("提现处理记录")
    @GetMapping("handler/list/{withdrawId}")
    public R<List<WithdrawHandlerListVo>> handlerList(@Validated @PathVariable("withdrawId")
                                                      @ApiParam(value = "提现ID", required = true)
                                                      @NotNull(message = "提现ID不能为空")
                                                      Long withdrawId) {
        // 用户提现处理记录
        List<SysUserWalletWithdrawHandler> handlerList = userWalletWithdrawHandlerService.getWithdrawHandlerList(withdrawId);
        List<WithdrawHandlerListVo> list = withdrawConverter.toHandlerList(handlerList);
        return R.ok(list, handlerList);
    }


    /**
     * 提现审核
     *
     * @return
     */
    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:user:withdraw:process')")
    @ApiOperation("提现审核")
    @PostMapping("process/{withdrawId}")
    @Log(title = "钱包提现", businessType = BusinessType.UPDATE)
    public R withdrawProcess(
            @PathVariable("withdrawId")
            @ApiParam(value = "提现ID", required = true)
            @NotNull(message = "提现ID不能为空")
            Long withdrawId,
            @Validated @RequestBody WithdrawProcessDto params) {

        if (params.getStatus() != WithdrawStatusEnum.PROCESS_ABORT && params.getStatus() != WithdrawStatusEnum.PROCESS_PASS) {
            throw new ServiceException("审核状态异常！");
        }
        // 获取提现信息
        userWalletWithdrawService.withdrawHandler(withdrawId, params.getStatus(), params.getOpinion());
        return R.ok();
    }

    /**
     * 提现审核-批量
     *
     * @return
     */
    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:user:withdraw:process:batch')")
    @ApiOperation("提现审核-批量")
    @PostMapping("process-batch")
    @Log(title = "钱包提现-批量", businessType = BusinessType.UPDATE)
    public R withdrawProcessBatch(@Validated @RequestBody WithdrawBatchProcessDto params) {
        if (Objects.isNull(params) || CollUtil.isEmpty(params.getWithdrawId())) {
            return R.fail("审核失败，参数错误");
        }
        if (params.getWithdrawId().size() > 1000) {
            return R.fail("审核失败，批量最大1000条");
        }
        //提现ID重复校验
        boolean hasDuplicates = params.getWithdrawId().stream()
                .distinct()
                .count() != params.getWithdrawId().size();
        if (hasDuplicates) {
            throw new ServiceException("审核失败，提现订单ID重复！");
        }
        if (params.getStatus() != WithdrawStatusEnum.PROCESS_ABORT && params.getStatus() != WithdrawStatusEnum.PROCESS_PASS) {
            throw new ServiceException("审核失败，状态异常！");
        }
        //校验ID正确性，状态是否为待审核状态
        List<SysUserWalletWithdraw> list = userWalletWithdrawService.list(new LambdaQueryWrapper<SysUserWalletWithdraw>()
                .in(SysUserWalletWithdraw::getId, params.getWithdrawId())
                .eq(SysUserWalletWithdraw::getStatus, WithdrawStatusEnum.WAIT_PROCESS));
        if (list.size() !=  params.getWithdrawId().size()) {
            throw new ServiceException("审核失败，提现订单ID错误");
        }
        // 获取提现信息
        for (SysUserWalletWithdraw item : list) {
            userWalletWithdrawService.withdrawHandler(item.getId(), params.getStatus(), params.getOpinion());
        }
        return R.ok();
    }
//
//    /**
//     * 提现结算
//     *
//     * @return
//     */
//    @PreAuthorize("@ss.hasPermi('web:user:wallet:settle')")
//    @ApiOperation("提现结算")
//    @PostMapping("settle/{withdrawId}")
//    public R withdrawSettle(
//            @PathVariable("withdrawId")
//            @ApiParam(value = "提现ID", required = true)
//            @NotNull(message = "提现ID不能为空")
//            Long withdrawId,
//            @Validated @RequestBody WithdrawProcessDto params) {
//
//        if (params.getStatus() != WithdrawStatusEnum.SETTLED && params.getStatus() != WithdrawStatusEnum.SETTLE_ABORT) {
//            throw new ServiceException("结算状态异常！");
//        }
//
//        SysUserWalletWithdrawHandler handler = new SysUserWalletWithdrawHandler();
//        handler.setWithdrawId(withdrawId);
//        handler.setOpinion(params.getOpinion());
//        handler.setStatus(params.getStatus());
//        handler.setHandlerUserId(getUserId());
//        handler.setHandlerUserName(getUsername());
//        userWalletWithdrawHandlerService.handler(handler);
//
//        return R.ok();
//    }

    /**
     * 余额提现列表总额数据
     * @param params
     * @return
     */
    @ApiOperation("余额提现列表总额数据")
    @GetMapping("list-total")
    public R<WithdrawListTotalVo> withdrawListTotal(@Validated GetWithdrawListDto params) {
        return userWalletWithdrawService.withdrawListTotal(params);
    }
    /**
     * 导出余额提现
     */
    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:user:withdraw:export')")
    @ApiOperation("用户钱包提现导出")
    @Log(title = "余额提现", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(GetWithdrawListDto params, HttpServletResponse response) {
        if (Objects.isNull(params) || Objects.isNull(params.getCreateTimeStart()) || Objects.isNull(params.getCreateTimeEnd())) {
            throw new ServiceException("请选择开始时间/结束时间");
        }
        if (LocalDateUtils.getDifferentDays(params.getCreateTimeStart().toLocalDate(), params.getCreateTimeEnd().toLocalDate()) > 7) {
            throw new ServiceException("开始结束时间不能超过7天");
        }
        List<WithdrawListExportVo> list = userWalletWithdrawService.export(params);
        ExcelUtil<WithdrawListExportVo> util = new ExcelUtil<>(WithdrawListExportVo.class);
        util.exportExcel(response, list, "余额提现");
    }
}
